import time
import network
import camera
import socket
from machine import Pin

# ====================== 配置区 ======================
WIFI_SSID = "LAPTOP-D3RPTUAA 6358"    # WiFi名称
WIFI_PWD = "19234949992.ch"           # WiFi密码
HTML_PORT = 8080                      # 网页服务端口
CAMERA_RESOLUTION = 3  # 降低分辨率减轻负担 (3=640x480, 2=320x240更稳定)

# 静态IP配置
STATIC_IP = '192.168.137.114'
SUBNET_MASK = '255.255.255.0'
GATEWAY = '192.168.137.1'
DNS = '114.114.114.114'

# ====================== 硬件初始化 ======================
led = Pin(4, Pin.OUT)  # 板载LED
led.value(0)

def init_camera():
    """初始化摄像头并测试捕获功能"""
    try:
        camera.init()
        camera.framesize(CAMERA_RESOLUTION)
        camera.quality(10)  # 降低画质提高稳定性
        # 测试捕获一帧
        test_frame = camera.capture()
        if not test_frame:
            raise Exception("摄像头能初始化但无法捕获图像")
        print(f"摄像头初始化成功，测试帧大小: {len(test_frame)} bytes")
        return True
    except Exception as e:
        print(f"摄像头初始化失败: {e}")
        # 硬件问题提示
        print("请检查摄像头排线是否插紧、镜头是否安装正确")
        return False

def init_wifi():
    """连接WiFi并返回IP"""
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.ifconfig((STATIC_IP, SUBNET_MASK, GATEWAY, DNS))
    wlan.connect(WIFI_SSID, WIFI_PWD)
    
    # 等待连接（带LED闪烁提示）
    timeout = 20
    while not wlan.isconnected() and timeout > 0:
        led.value(1)
        time.sleep(0.3)
        led.value(0)
        time.sleep(0.3)
        timeout -= 1
    
    if not wlan.isconnected():
        print("WiFi连接失败！")
        return None
    
    ip = wlan.ifconfig()[0]
    print(f"WiFi已连接，IP: {ip}")
    led.value(0)  # 常亮表示连接成功
    return ip

def start_html_server(ip):
    html = """<html><body><img src="/stream"></body></html>"""
    addr = socket.getaddrinfo(ip, HTML_PORT)[0][-1]
    s = socket.socket()
    s.bind(addr)
    s.listen(1)
    print(f"http://{ip}:{HTML_PORT}")
    
    while True:
        cl, addr = s.accept()
        req = cl.recv(1024)
        if b"GET /stream" in req:
            # 严格MJPEG响应头（必须包含 boundary）
            cl.send(b'HTTP/1.1 200 OK\r\n')
            cl.send(b'Content-Type: multipart/x-mixed-replace; boundary=ESP32CAM\r\n\r\n')
            
            while True:
                frame = camera.capture()  # 获取JPEG帧
                if not frame:
                    continue  # 跳过空帧
                
                # 构建MJPEG帧（严格格式！）
                part = b''
                part += b'--ESP32CAM\r\n'  # 边界必须和响应头一致
                part += b'Content-Type: image/jpeg\r\n'
                part += f'Content-Length: {len(frame)}\r\n\r\n'.encode()
                part += frame
                part += b'\r\n'
                
                # 确保完整发送（应对长数据）
                try:
                    cl.send(part)
                except OSError as e:
                    print(f"发送失败: {e}")
                    cl.close()
                    break
                time.sleep(0.1)
        else:
            cl.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n' + html.encode())
            cl.close()

# ====================== 主程序 ======================
def main():
    # 分步初始化，便于定位问题
    print("初始化摄像头...")
    if not init_camera():
        print("摄像头初始化失败，程序退出")
        return
        
    print("连接WiFi...")
    ip = init_wifi()
    if not ip:
        print("WiFi连接失败，程序退出")
        return
        
    print("启动网页服务...")
    try:
        start_html_server(ip)
    except Exception as e:
        print(f"程序异常: {e}")
    finally:
        camera.deinit()
        led.value(0)
        print("程序已退出")

if __name__ == "__main__":
    main()
